Git: advanced concepts
In a nutshell
- Versioning: keep every change made to files
- Branching: develop new features while fixing bugs on a production release
- Decentralized & Collaborative
Outline
- Git internals
- 5-min break
- Common commands
- 5-min break
- Tips and tricks for efficient programming
What’s Git?
First of all, Git lives in .git/
What’s Git?
Second of all, Git “is” a tree of commits.
What’s a commit then?
- A snapshot of the whole codebase at a given time
- This snapshot is represented as a SHA-1 hash
SHA-1
SHA-1 is an algorithm that takes some data as input and generates a unique 40 character string from it.
The SHA-1 hash depends on…
- The commit message
- The committer info
- The commit date
- The author info
- The authoring date
- The source tree (= the state of the code)
- The commit’s parent commits
If any of these values change, the SHA-1 changes.
What’s Git again?
- Git holds a tree of commits
What’s Git again?
- Git holds a tree of commits
- Commits have 1 or 2 parents tops
What’s Git again?
- Git holds a tree of commits
- Commits have 1 or 2 parents tops
- There are special cases of orphan commits (no parents) such as the first commit
What’s Git again?
- Git holds a tree of commits
- Commits have 1 or 2 parents tops
- There are special cases of orphan commits (no parents) such as the first commit
- A branch is a label/tag/pointer/reference (pick the word of your liking) pointing towards a commit
Two types of branches
- Local writable branches
- Distant read-only branches (prefixed with origin/)
Special pointers
HEAD: points to the currently checked out commit
@: an alias for HEAD
HEAD~ vs HEAD^
ref~ is shorthand for ref~1 and means the commit’s first parent. ref~2 means the commit’s first parent’s first parent. And so on.
ref^ is shorthand for ref^1 and means the commit’s first parent. But where the two differ is that ref^2 means the commit’s second parent
Let’s look under the hood
Remember: Git lives in .git/
$ lstree .git/refs
.git/refs
+--- remotes
| +--- origin
| | +--- DOC-38-FIX
| | +--- master
| | +--- PAT-256
| | +--- production
+--- tags
| +--- first-commit
+--- heads
| +--- master
| +--- feature-xyz
| +--- production
$ cat .git/refs/heads/master
fgjh75955bd59c7ef27d0c55b9165db6a2b768ce
$ cat .git/HEAD
ref: refs/heads/feature-xyz
Everything is a pointer pointing at a commit.
Common commands

Some vocabulary first
- Workspace / working directory
- Index / staging area
- Local repository
git pull
= git fetch + git merge
git merge
To fast forward, or not to fast forward…
git rebase
git rebase origin/master
git rebase -i origin/master
git rebase --onto origin/master SHA-1
Rebasing rewrites history.
git diff
git diff commit1..commit2
git diff commit1..
git diff --staged
git show
git show SHA-1
git show --stat
git checkout
- Create branch:
git checkout -b feature origin/master
- Checkout branch:
git checkout BRANCH
- Checkout files at specific revision:
git checkout SHA-1 -- file1 file2
git branch
git branch -vv
git branch -m new-name
git merge-base
git merge-base origin/master HEAD
==> Common ancestor between origin/master & HEAD
(= between your branch and master)
git revert <SHA-1>

git log
git log -p -- package.json
git log --oneline $(git merge-base @ "origin/master")..
git log --stat
git reset
- Unstage files:
git reset file
- Move branch to other commit:
git reset --hard SHA-1
git bisect
Finds the commit which introduced a bug.
git reflog
History of all actions performed.
Tips and tricks
for efficient programming

Use the CLI and RTFM
Forget about the GUI
man git-merge

git rebase -i $(git merge-base origin/master HEAD)
When you want to edit/squash some commits and leave other untouched, while keeping most SHA-1 hashes
Delete merged branches
git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -D
Built-in aliases for common Git commands
alias | grep git
(go ahead, run the command right now)
That’s it! Thanks.
